package terra.ui.wnd;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.gui.AbstractComponent;
import org.newdawn.slick.gui.ComponentListener;
import org.newdawn.slick.gui.GUIContext;

import terra.slick.GameState;
import terra.ui.GUI;
import terra.util.FontUtils;

/** Абстрактный класс, описывающий любое окно, используемое в интерфейсе пользователя
 * Окно может быть статичным, либо перетаскиваемым
 * может иметь всплывающую подсказку
 */

public abstract class AbstractWindow extends AbstractComponent {
	
	private Shape area = new Rectangle(0,0,1,1);
	private boolean over,visible = true,draggable = true,hasTooltip = false;
	private String tooltip;
	long overTime = 0;
	protected long lastOpenTime = 0;
	
	public AbstractWindow(GUIContext container,ComponentListener listener) {
		super(container);
		addListener(listener);
	}

	public abstract void update(int delta);
	
	public void render(GUIContext container, Graphics g) throws SlickException {
		if (hasTooltip)
			if (isOver() && System.currentTimeMillis()-overTime >= 1000 )
			{
				g.setColor(Color.darkGray);
				g.drawRect(GameState.getInstance().getX(), GameState.getInstance().getY()-g.getFont().getLineHeight(), g.getFont().getWidth(tooltip)+6, g.getFont().getLineHeight());
				g.setColor(Color.lightGray);
				g.fillRect(GameState.getInstance().getX()+1, GameState.getInstance().getY()-g.getFont().getLineHeight()+1, g.getFont().getWidth(tooltip)+6-2, g.getFont().getLineHeight()-2);
				FontUtils.drawLeft(g.getFont(), tooltip, GameState.getInstance().getX()+2, GameState.getInstance().getY()-g.getFont().getLineHeight(), Color.darkGray);
			}
	}
	
	@Override
	public void setLocation(int x, int y) {
		if (area != null)
		{
			if (x >= 0 && x+getWidth() < container.getWidth())
				area.setLocation(x, getY());
			else if (x < 0)
				area.setLocation(0, getY());
			else
				area.setLocation(container.getWidth()-getWidth(), getY());
			
			if (y >= 0 && y+getHeight() < container.getHeight())
				area.setLocation(getX(), y);
			else if (y < 0)
				area.setLocation(getX(), 0);
			else
				area.setLocation(getX(), container.getHeight()-getHeight());
		}
		//overTime = System.currentTimeMillis();
	}

	@Override
	public int getX() {
		return (int) area.getX();
	}

	@Override
	public int getY() {
		return (int) area.getY();
	}

	@Override
	public int getWidth() {
		return (int) area.getWidth();
	}

	@Override
	public int getHeight() {
		return (int) area.getHeight();
	}

	@Override
	public void mouseMoved(int oldx, int oldy, int newx, int newy) {
		if (isVisible())
			setOver(area.contains(newx, newy));
	}
	
	@Override
	public void mouseDragged(int oldx, int oldy, int newx, int newy) {
		if (isVisible() && isDraggable() && isOver() && hasFocus())
			setLocation(getX()+ newx-oldx,getY()+ newy-oldy);
		else
			mouseMoved(oldx, oldy, newx, newy);
	}

	@Override
	public void mousePressed(int button, int mx, int my) {
		setOver(area.contains(mx, my));
		if (hasFocus() && isVisible())
			consumeEvent();
		//if (isOver())

	}
	
	@Override
	public void mouseReleased(int button, int mx, int my) {
		if (hasFocus() && isVisible())
			consumeEvent();
		//super.mouseReleased(button, mx, my);
		setOver(area.contains(mx, my));
	}

	public boolean isOver() {
		return over;
	}

	public void setOver(boolean over) {

		if (this.over != over)
			setFocus(over);
		this.over = over;
		overTime = System.currentTimeMillis();
	}

	public boolean isVisible() {
		return visible;
	}

	public void setVisible(boolean visible) {
		this.visible = visible;
	}

	public Shape getArea() {
		return area;
	}

	public void setArea(Shape area) {
		this.area = area;
	}

	public boolean isDraggable() {
		return draggable;
	}

	public void setDraggable(boolean draggable) {
		this.draggable = draggable;
	}

	public String getTooltip() {
		return tooltip;
	}

	public void setTooltip(String tooltip) {
		this.tooltip = tooltip;
		setHasTooltip(true);
	}

	public boolean hasTooltip() {
		return hasTooltip;
	}

	public void setHasTooltip(boolean hasTooltip) {
		this.hasTooltip = hasTooltip;
	}	
	
	@Override 
	public void setFocus(boolean focus) {

		if (focus)
		{
			if (GUI.hasFocus() == null || GUI.hasFocus() == this)
			{
				GUI.ui.remove(this);
				GUI.ui.add(0,this);
			}
			else
				return;
		}
		else 
		{
			if (GUI.ui.get(0) != this)
				focusLost();
		}
		super.setFocus(focus);
	}

	public void focusLost()
	{

	}
	
}
